#include "Engine.hpp"
#include "GameWorld.hpp"
#include "RenderSystem.hpp"
#include "FirstPersonMoverSystem.hpp"

using namespace Nano;

class Game : public GameState<Game> {
public:
    GameWorld world;
    RenderSystem* renderer;
    GameObject* camera;
    GameObject* cube;
    float rotation;
    
    void Initialize() {
        
        world.CreateSystem<RenderSystem>();
        world.CreateSystem<FirstPersonMoverSystem>()->Input = &Input;
        
        camera = world.CreateObject();
        camera->AddComponent<Camera>()->Viewport = Viewport();
        camera->AddComponent<Transform>()->Position = { 0, 0, 10 };
        camera->GetComponent<Camera>()->FieldOfView = 40;
        camera->AddComponent<FirstPersonMover>();
        
        cube = world.CreateObject();
        cube->AddComponent<Transform>();
        cube->AddComponent<Mesh>()->AddCube(0, 1);
        cube->AddComponent<Material>();
        cube->AddComponent<TextureComponent>()->Texture().LoadFromPng("rock.png");
        
        Mesh::VerticesList& verts = cube->GetComponent<Mesh>()->Vertices();
        
        for (int i=0; i<verts.size(); i++) {
            verts[i].Color = Colour::HslToRgb(i * 10, 1, 1, 1);
        }
        
        rotation = 0;
        
        Input.TouchDown += event_handler(this, &Game::Down);
        Input.TouchUp += event_handler(this, &Game::Up);
    }
    
    void Down(TouchEvent e) {
        std::cout<<"Down :  Index: " << e.Index << " Position : " << e.Position << std::endl;
    }
    
    void Up(TouchEvent e) {
        std::cout<<"Up :  Index: " << e.Index << " Position : " << e.Position << std::endl;
    }

    void Update(float dt) {
        cube->GetComponent<Transform>()->Rotation = Quaternion(rotation, Vector3(1,0.2f,0.5f).Normalized());
       // camera->AddComponent<Transform>()->Position = {0,0, 2 + (0.5f + sinf(rotation) * 0.5f) * 20 };
        rotation += dt;
        world.Update(dt);
    }
    
    void Render() {
        world.Render();
    }
};

int main(int argc, char** argv) {
    Engine e;
    e.Start<Game>(640,480, false);
	return 0;
}